package util

import (
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"time"
)

const JWT_KEY = "secret" //jwt秘钥
const DEFAULT_EXPIRE_SECONDS  = time.Hour * 5  //默认有效期
// Claims custom token
type Claims struct {
	UserId  int  // 用户ID
	UserType  uint8  // 用户ID
	jwt.StandardClaims
}

// CreateToken create token
func CreateToken(claims *Claims) (signedToken string, success bool) {
	claims.ExpiresAt = time.Now().Add(DEFAULT_EXPIRE_SECONDS).Unix()
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedToken, err := token.SignedString([]byte(JWT_KEY))
	if err != nil {
		return
	}

	success = true
	return
}

// ValidateToken validate token
func ValidateToken(signedToken string) (claims *Claims, success bool) {
	token, err := jwt.ParseWithClaims(signedToken, &Claims{},
		func(token *jwt.Token) (interface{}, error) {
			//if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			//	return nil, fmt.Errorf("unexpected login method %v", token.Header["alg"])
			//}
			return []byte(JWT_KEY), nil
		})

	if err != nil {
		fmt.Println(signedToken)
		fmt.Println(err)
		return
	}

	claims, ok := token.Claims.(*Claims)
	if ok && token.Valid {
		success = true
		return
	}

	return
}

//刷新jwt token
func RefreshToken(signedToken string)  (newSignedToken string, success bool){
	// first get previous token
	token, err := jwt.ParseWithClaims(signedToken, &Claims{},
		func(token *jwt.Token) (interface{}, error) {
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, fmt.Errorf("unexpected login method %v", token.Header["alg"])
			}
			return []byte(JWT_KEY), nil
		})
	if err != nil {
		return
	}
	claims, ok := token.Claims.(*Claims)
	if ok && token.Valid {
		return
	}

	// generate new token with new claims
	claims.ExpiresAt = time.Now().Add(DEFAULT_EXPIRE_SECONDS).Unix()
	token = jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	newSignedToken, err = token.SignedString([]byte(JWT_KEY))
	if err != nil {
		fmt.Println("generate new fresh json web token failed !! error :", err)
		return
	}
	success = true
	return
}